home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / SourceCode / MiscKit1.7.1 / MiscKit / Palettes / MiscSoundPalette / MiscSoundUtil.subproj / MiscSoundTracker.m < prev    next >
Encoding:
Text File  |  1995-03-25  |  12.4 KB  |  655 lines

  1. /*
  2.  
  3. MiscSoundTracker
  4. Version 1.2
  5. Copyright (c) 1995 by Sean Luke
  6. Donated to the MiscKit
  7.  
  8. Permission to use, copy, modify, and distribute this material 
  9. for any purpose and without fee, under the restrictions as noted 
  10. in the MiscKit copyright notice, is hereby granted, provided that
  11. the MiscKit copyright notice and this permission notice 
  12. appear in all source copies, and that the author's name shall not
  13. be used in advertising or publicity pertaining to this 
  14. material without the specific, prior written permission 
  15. of the author.  SEAN O. LUKE  MAKES NO REPRESENTATIONS ABOUT THE
  16. ACCURACY OR SUITABILITY OF THIS MATERIAL FOR ANY PURPOSE.  
  17. IT IS PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
  18.  
  19. */
  20.  
  21. #import "MiscSoundTracker.h"
  22. #import <stdio.h>
  23.  
  24. @implementation MiscSoundTracker
  25.  
  26. // KNOWN BUGS:  NeXT's sound object does not release sampling rate information
  27. // properly.  Hence, the tracker cannot get seconds information correctly,
  28. // when recording, and so must rely on a preset default for its sampling
  29. // rate in returning seconds.
  30.  
  31. // also, samples do not keep up with pausing.
  32.  
  33.  
  34.  
  35. // timed entry procedure for periodically updating (shadow here)
  36.  
  37. DPSTimedEntryProc SOUNDTRACKER_update_tracker
  38.     (DPSTimedEntry teNum,double now, void* the_tracker);
  39.  
  40.  
  41. - init
  42.     {
  43.     [super init];
  44.     running=NO;
  45.     default_sampling_rate=SOUNDTRACKER_DEFAULT_SAMPLING_RATE;
  46.     send_type=SOUNDTRACKER_SEND_TYPE_SAMPLES;
  47.     refresh=SOUNDTRACKER_TIMED_ENTRY_SPEED;
  48.     teNum=0;
  49.     //printf ("Init\n");
  50.     return self;
  51.     }
  52.  
  53. - awake
  54.     {
  55.     [super awake];
  56.     teNum=0;
  57.     //printf ("Awake\n");
  58.     return self;
  59.     }
  60.  
  61.  
  62. - _update
  63.     {
  64.     //printf("Updating\n");
  65.     
  66.     // first we check to see if there's a sound lock and if so,
  67.     // if we should proceed...
  68.     
  69.     if (sound!=NULL&&
  70.             (send_type==SOUNDTRACKER_SEND_TYPE_SAMPLES||
  71.             send_type==SOUNDTRACKER_SEND_TYPE_RATIO||
  72.             send_type==SOUNDTRACKER_SEND_TYPE_PERCENT||
  73.             send_type==SOUNDTRACKER_SEND_TYPE_SECONDS))
  74.             {
  75.             id actual_sound;
  76.             int status;
  77.             
  78.             if ([sound isKindOf:[Sound class]]) 
  79.                 {actual_sound=sound;}
  80.             else if ([sound isKindOf:[SoundView class]])
  81.                 {actual_sound=[sound soundBeingProcessed];}
  82.             else return NULL;        // not a sound or soundview!!!
  83.             
  84.             status=[actual_sound status];
  85.             if (status==NX_SoundStopped||
  86.                 status==NX_SoundInitialized||
  87.                 status==NX_SoundFreed) return self;        
  88.                     // sound's not doing anything...
  89.             }
  90.     
  91.     if (target!=NULL)
  92.         {
  93.         //printf ("Target Not Null\n");
  94.         if (send_type==SOUNDTRACKER_SEND_TYPE_SAMPLES||
  95.             send_type==SOUNDTRACKER_SEND_TYPE_MUTE||
  96.             send_type==SOUNDTRACKER_SEND_TYPE_DEEMPHASIS)
  97.             {
  98.             //printf ("Sending Take Message\n");
  99.             if (![target respondsTo:@selector(takeIntValueFrom:)])
  100.                  return NULL;
  101.             [target takeIntValueFrom:self];
  102.             }
  103.         else if (send_type==SOUNDTRACKER_SEND_TYPE_RATIO||
  104.                 send_type==SOUNDTRACKER_SEND_TYPE_PERCENT)
  105.             {
  106.             int status=[sound status];
  107.             if (status==NX_SoundRecording||
  108.                 status==NX_SoundRecordingPaused)
  109.                 {
  110.                 [self clearTarget];
  111.                 }
  112.             else
  113.                 {
  114.                 if (![target respondsTo:@selector(takeFloatValueFrom:)])
  115.                     return NULL;
  116.                 [target takeFloatValueFrom:self];
  117.                 }
  118.             }
  119.         else if (send_type==SOUNDTRACKER_SEND_TYPE_SECONDS||
  120.                 send_type==SOUNDTRACKER_SEND_TYPE_LEFT||
  121.                 send_type==SOUNDTRACKER_SEND_TYPE_RIGHT||
  122.                 send_type==SOUNDTRACKER_SEND_TYPE_MONO)
  123.             {
  124.             if (![target respondsTo:@selector(takeFloatValueFrom:)])
  125.                  return NULL;
  126.             [target takeFloatValueFrom:self];
  127.             }
  128.         else printf ("SOUNDTRACKER Error:  No Send Type\n");
  129.         }
  130.     return self;
  131.     }
  132.  
  133.  
  134. - setRefresh:(float) number_seconds
  135.     {
  136.     if (number_seconds>0)
  137.         {
  138.         refresh=number_seconds;
  139.         if (teNum) 
  140.             {
  141.             DPSRemoveTimedEntry(teNum);
  142.             teNum=DPSAddTimedEntry(refresh, 
  143.                 (DPSTimedEntryProc) SOUNDTRACKER_update_tracker,
  144.                 (void*) self, (int) NX_RUNMODALTHRESHOLD);
  145.             }
  146.         }
  147.     return self;
  148.     }
  149.  
  150. - setRefreshToMe:sender
  151.     {
  152.     if ([sender respondsTo:@selector(floatValue)])
  153.         [self setRefresh:[sender floatValue]];
  154.     return self;
  155.     }
  156.  
  157.  
  158. - (float)refresh
  159.     {
  160.     return refresh;
  161.     }    
  162.  
  163. - free
  164.     {
  165.     if (output_device!=NULL) [output_device free];
  166.     if (teNum) DPSRemoveTimedEntry(teNum);
  167.     return [super free];
  168.     }
  169.  
  170.  
  171. - setSound:this_sound_or_soundview
  172.     {
  173.     sound=this_sound_or_soundview;
  174.     return self;
  175.     }
  176.  
  177.  
  178. - sound
  179.     {
  180.     return sound;
  181.     }
  182.  
  183. - setDefaultSamplingRate:(float) this_rate
  184.     {
  185.     if (this_rate!=0.0) default_sampling_rate=this_rate;
  186.     return self;
  187.     }
  188.  
  189. - (float)defaultSamplingRate
  190.     {
  191.     return default_sampling_rate;
  192.     }
  193.     
  194. - setTarget:this_target
  195.     {
  196.     target=this_target;
  197.     return self;
  198.     }
  199.  
  200.  
  201. - target
  202.     {
  203.     return target;
  204.     }
  205.  
  206.  
  207. - run
  208.     {
  209.     running=YES;
  210.     if (!teNum) teNum=DPSAddTimedEntry(refresh, 
  211.             (DPSTimedEntryProc) SOUNDTRACKER_update_tracker,
  212.             (void*) self, (int) NX_RUNMODALTHRESHOLD);
  213.     return self;
  214.     }
  215.  
  216.  
  217. - stop
  218.     {
  219.     running=NO;
  220.     if (teNum) DPSRemoveTimedEntry(teNum);
  221.     teNum=0;
  222.     return self;
  223.     }
  224.  
  225.  
  226. - sendSamples
  227.     {
  228.     send_type=SOUNDTRACKER_SEND_TYPE_SAMPLES;
  229.     return self;
  230.     }
  231.  
  232.  
  233. - sendSeconds
  234.     {
  235.     send_type=SOUNDTRACKER_SEND_TYPE_SECONDS;
  236.     return self;
  237.     }
  238.  
  239.  
  240. - sendRatio
  241.     {
  242.     send_type=SOUNDTRACKER_SEND_TYPE_RATIO;
  243.     return self;
  244.     }
  245.     
  246. - sendPercent
  247.     {
  248.     send_type=SOUNDTRACKER_SEND_TYPE_PERCENT;
  249.     return self;
  250.     }
  251.     
  252. - sendLeft
  253.     {
  254.     send_type=SOUNDTRACKER_SEND_TYPE_LEFT;
  255.     return self;
  256.     }
  257.     
  258.  
  259. - sendRight
  260.     {
  261.     send_type=SOUNDTRACKER_SEND_TYPE_RIGHT;
  262.     return self;
  263.     }
  264.     
  265.  
  266. - sendMono
  267.     {
  268.     send_type=SOUNDTRACKER_SEND_TYPE_MONO;
  269.     return self;
  270.     }
  271.     
  272.  
  273. - sendMute
  274.     {
  275.     send_type=SOUNDTRACKER_SEND_TYPE_MUTE;
  276.     return self;
  277.     }
  278.     
  279. - sendDeemphasis
  280.     {
  281.     send_type=SOUNDTRACKER_SEND_TYPE_DEEMPHASIS;
  282.     return self;
  283.     }
  284.  
  285. - sendLeftPeak
  286.     {
  287.     send_type=SOUNDTRACKER_SEND_TYPE_LEFT_PEAK;
  288.     return self;
  289.     }
  290.  
  291. - sendRightPeak
  292.     {
  293.     send_type=SOUNDTRACKER_SEND_TYPE_RIGHT_PEAK;
  294.     return self;
  295.     }
  296.     
  297. - sendMonoPeak
  298.     {
  299.     send_type=SOUNDTRACKER_SEND_TYPE_MONO_PEAK;
  300.     return self;
  301.     }
  302.  
  303. - setSendType:(int)this_format
  304.     {
  305.     if (this_format==SOUNDTRACKER_SEND_TYPE_SAMPLES||
  306.         this_format==SOUNDTRACKER_SEND_TYPE_SECONDS||
  307.         this_format==SOUNDTRACKER_SEND_TYPE_RATIO||
  308.         this_format==SOUNDTRACKER_SEND_TYPE_PERCENT||
  309.         this_format==SOUNDTRACKER_SEND_TYPE_LEFT||
  310.         this_format==SOUNDTRACKER_SEND_TYPE_RIGHT||
  311.         this_format==SOUNDTRACKER_SEND_TYPE_MONO||
  312.         this_format==SOUNDTRACKER_SEND_TYPE_MUTE||
  313.         this_format==SOUNDTRACKER_SEND_TYPE_DEEMPHASIS||
  314.         this_format==SOUNDTRACKER_SEND_TYPE_LEFT_PEAK||
  315.         this_format==SOUNDTRACKER_SEND_TYPE_RIGHT_PEAK||
  316.         this_format==SOUNDTRACKER_SEND_TYPE_MONO_PEAK)
  317.         {send_type=this_format;return self;}
  318.     return NULL;
  319.     }
  320.  
  321. - (int) sendType
  322.     {
  323.     return send_type;
  324.     }
  325.  
  326. - (float) floatValue    
  327.     {
  328.     if (send_type==SOUNDTRACKER_SEND_TYPE_SECONDS)
  329.         {
  330.         if (sound!=NULL)
  331.             {
  332.             if ([sound isKindOf:[Sound class]])
  333.                 {
  334.                 float n=[sound samplingRate];
  335.                 //printf ("%f\n",n);
  336.                 if (n==0.0) n=default_sampling_rate;
  337.                 return ((float)[sound samplesProcessed])/n;
  338.                 }
  339.             else if ([sound isKindOf:[SoundView class]])
  340.                 {
  341.                 id snd1=[sound soundBeingProcessed];
  342.                 float n=[snd1 samplingRate];
  343.                 //printf ("%f\n",n);
  344.                 if (n==0.0) n=default_sampling_rate;
  345.                 return ((float)[snd1 samplesProcessed])/n;
  346.                 }
  347.             }
  348.         }
  349.     else if (send_type==SOUNDTRACKER_SEND_TYPE_RATIO)
  350.         {
  351.         if (sound!=NULL)
  352.             {
  353.             if ([sound isKindOf:[Sound class]])
  354.                 {
  355.                 //int status=[sound status];  // no use right now
  356.                                     
  357.                 return ((float)[sound samplesProcessed])/
  358.                     ((float)[sound sampleCount]);
  359.                 }
  360.             else if ([sound isKindOf:[SoundView class]])
  361.                 {
  362.                 id snd1=[sound soundBeingProcessed];
  363.                 //int status=[snd1 status];  // no use right now
  364.                     
  365.                 return ((float)[snd1 samplesProcessed])/
  366.                     ((float)[snd1 sampleCount]);
  367.                 }
  368.             }
  369.         }
  370.     else if (send_type==SOUNDTRACKER_SEND_TYPE_PERCENT)
  371.         {
  372.         if (sound!=NULL)
  373.             {
  374.             if ([sound isKindOf:[Sound class]])
  375.                 {
  376.                 //int status=[sound status];  // no use right now
  377.                                     
  378.                 return ((float)[sound samplesProcessed])/
  379.                     ((float)[sound sampleCount])*100;
  380.                 }
  381.             else if ([sound isKindOf:[SoundView class]])
  382.                 {
  383.                 id snd1=[sound soundBeingProcessed];
  384.                 //int status=[snd1 status];  // no use right now
  385.                     
  386.                 return ((float)[snd1 samplesProcessed])/
  387.                     ((float)[snd1 sampleCount])*100;
  388.                 }
  389.             }
  390.         }
  391.     else if (send_type==SOUNDTRACKER_SEND_TYPE_LEFT)
  392.         {
  393.         float l,r;
  394.         [Sound getVolume:&l:&r];
  395.         return l;
  396.         }
  397.     else if (send_type==SOUNDTRACKER_SEND_TYPE_RIGHT)
  398.         {
  399.         float l,r;
  400.         [Sound getVolume:&l:&r];
  401.         return r;
  402.         }
  403.     else if (send_type==SOUNDTRACKER_SEND_TYPE_MONO)
  404.         {
  405.         float l,r;
  406.         [Sound getVolume:&l:&r];
  407.         return (l+r)/2.0;
  408.         }
  409.     else if (send_type==SOUNDTRACKER_SEND_TYPE_LEFT_PEAK)
  410.         {
  411.         float l,r;
  412.         
  413.         // try to grab resources
  414.         if (output_device==NULL) output_device=[[NXSoundOut alloc] init];
  415.         
  416.         if (output_device!=NULL)
  417.             {
  418.             [output_device getPeakLeft:&l right:&r];
  419.             return l;
  420.             }
  421.         // else...return -1.0 as shown below
  422.         }
  423.     else if (send_type==SOUNDTRACKER_SEND_TYPE_RIGHT_PEAK)
  424.         {
  425.         float l,r;
  426.         
  427.         // try to grab resources
  428.         if (output_device==NULL) output_device=[[NXSoundOut alloc] init];
  429.         
  430.         if (output_device!=NULL)
  431.             {
  432.             [output_device getPeakLeft:&l right:&r];
  433.             return r;
  434.             }
  435.         // else...return -1.0 as shown below
  436.         }
  437.     else if (send_type==SOUNDTRACKER_SEND_TYPE_MONO_PEAK)
  438.         {
  439.         float l,r;
  440.         
  441.         // try to grab resources
  442.         if (output_device==NULL) output_device=[[NXSoundOut alloc] init];
  443.         
  444.         if (output_device!=NULL)
  445.             {
  446.             [output_device getPeakLeft:&l right:&r];
  447.             return (l+r)/2.0;
  448.             }
  449.         // else...return -1.0 as shown below
  450.         }
  451.  
  452.     else printf ("SOUNDTRACKER Error:  Wrong send type for floatValue\n");
  453.     return -1.0;
  454.     }
  455.  
  456.  
  457. - (int) intValue    
  458.     {
  459.     //printf ("Okay\n");
  460.     if (send_type==SOUNDTRACKER_SEND_TYPE_SAMPLES)
  461.         {
  462.         if (sound!=NULL)
  463.             {
  464.             if ([sound isKindOf:[Sound class]])
  465.                 {
  466.                 return [sound samplesProcessed];
  467.                 }
  468.             else if ([sound isKindOf:[SoundView class]])
  469.                 {
  470.                 id snd1=[sound soundBeingProcessed];
  471.                 return [snd1 samplesProcessed];
  472.                 }
  473.             }
  474.         }
  475.     else if (send_type==SOUNDTRACKER_SEND_TYPE_MUTE)
  476.         {
  477.         return (int) [Sound isMuted];
  478.         }
  479.     else if (send_type==SOUNDTRACKER_SEND_TYPE_DEEMPHASIS)
  480.         {
  481.         // try to grab resources
  482.         if (output_device==NULL) output_device=[[NXSoundOut alloc] init];
  483.         
  484.         if (output_device!=NULL)
  485.             {
  486.             return (int) [output_device doesDeemphasize];
  487.             }
  488.         else return NO;
  489.         }
  490.     else printf ("SOUNDTRACKER Error:  Wrong send type for intValue\n");
  491.     return -1;
  492.     }
  493.  
  494.  
  495. - setVolumeTo:sender    
  496.     {
  497.     float l,r,x;
  498.     [Sound getVolume:&l:&r];
  499.     if (! [sender respondsTo:@selector(floatValue)]) return NULL;
  500.     x=[sender floatValue];
  501.     if (x<0||x>1) return NULL;
  502.     if (send_type==SOUNDTRACKER_SEND_TYPE_LEFT) [Sound setVolume:x:r];
  503.     if (send_type==SOUNDTRACKER_SEND_TYPE_RIGHT) [Sound setVolume:l:x];
  504.     if (send_type==SOUNDTRACKER_SEND_TYPE_MONO) [Sound setVolume:x:x];
  505.     return self;
  506.     }
  507.  
  508.  
  509. - setMuteTo:sender    
  510.     {
  511.     int x;
  512.     if (! [sender respondsTo:@selector(intValue)]) return NULL;
  513.     x=[sender intValue];
  514.     if (x!=0) x=1;
  515.     [Sound setMute:(BOOL)x];
  516.     return self;
  517.     }
  518.  
  519. - setDeemphasisTo:sender    
  520.     {
  521.     int x;
  522.     if (! [sender respondsTo:@selector(intValue)]) return NULL;
  523.     x=[sender intValue];
  524.     if (x!=0) x=1;
  525.     
  526.     // try to grab resources
  527.     if (output_device==NULL) output_device=[[NXSoundOut alloc] init];
  528.     
  529.     if (output_device!=NULL)
  530.         {
  531.         [output_device setDeemphasis:x];
  532.         }
  533.     return self;
  534.     }
  535.  
  536.  
  537. - run:sender
  538.     {
  539.     return [self run];
  540.     }
  541.  
  542.  
  543. - stop:sender
  544.     {
  545.     return [self stop];
  546.     }
  547.  
  548.  
  549. - sendSamples:sender
  550.     {
  551.     return [self sendSamples];
  552.     }
  553.  
  554.  
  555. - sendSeconds:sender
  556.     {
  557.     return [self sendSeconds];
  558.     }
  559.  
  560.  
  561. - sendRatio:sender
  562.     {
  563.     return [self sendRatio];
  564.     }
  565.  
  566. - sendPercent:sender
  567.     {
  568.     return [self sendPercent];
  569.     }
  570.  
  571. - sendLeft:sender
  572.     {
  573.     return [self sendLeft];
  574.     }
  575.  
  576. - sendRight:sender
  577.     {
  578.     return [self sendRight];
  579.     }
  580.  
  581. - sendMono:sender
  582.     {
  583.     return [self sendMono];
  584.     }
  585.  
  586. - sendMute:sender
  587.     {
  588.     return [self sendMute];
  589.     }
  590.     
  591. - sendDeemphasis:sender
  592.     {
  593.     return [self sendDeemphasis];
  594.     }
  595.     
  596. - sendLeftPeak:sender
  597.     {
  598.     return [self sendLeftPeak];
  599.     }
  600.     
  601. - sendRightPeak:sender
  602.     {
  603.     return [self sendRightPeak];
  604.     }    
  605.     
  606. - sendMonoPeak:sender
  607.     {
  608.     return [self sendMonoPeak];
  609.     }
  610.  
  611. - read:(NXTypedStream*) stream
  612.     {
  613.     [super read:stream];
  614.     NXReadTypes(stream,"iff",&send_type,&refresh,&default_sampling_rate);
  615.     return self;
  616.     }
  617.  
  618. - write:(NXTypedStream*) stream
  619.     {
  620.     [super write:stream];
  621.     NXWriteTypes(stream,"iff",&send_type,&refresh,&default_sampling_rate);
  622.     return self;
  623.     }
  624.  
  625. - clearTarget
  626.     {
  627.     if ([target respondsTo:@selector(setStringValue:)])
  628.         {
  629.         [target setStringValue:""];
  630.         }
  631.     else [target setIntValue:0];
  632.     return self;
  633.     }
  634.  
  635. - (const char*) getInspectorClassName
  636.     {
  637.     return "MiscSoundTrackerInspector";
  638.     }
  639.  
  640. @end
  641.  
  642.  
  643.  
  644. // timed entry procedure for periodically updating
  645.  
  646. DPSTimedEntryProc SOUNDTRACKER_update_tracker
  647.     (DPSTimedEntry teNum,double now, void* the_tracker)
  648.     {
  649.     MiscSoundTracker* temp_tracker=(MiscSoundTracker*) the_tracker;
  650.     [temp_tracker _update];
  651.     return (void*) NULL;
  652.     }
  653.  
  654.  
  655.